from .a4_train_methods import get_trained_brain, yield_series_trained_brain
from .a2_load_dataset import prepare_sample_with_noise, yield_samples_with_series_noise_strength
from .a1_file_version_control_system import result_vcs


def get_analyse_result(samples, brain, version=None):
    """

    :param samples:
    :param brain:
    :param version:
    :return: vr, ar, cr
    """
    name = 'brain_d' + str(brain.depth) + '_s' + str(brain.node_size) + 'analyse_result.result'
    if version is not None:
        return result_vcs.load(name, version)

    vdin, adin, label = samples

    vr, ar, cr = brain.analyse((vdin, adin))

    analyse_result = (vr, ar, cr)

    result_vcs.save(analyse_result, name)

    return analyse_result


def network_analyse_result_name(noise_strength, node_size, depth=1):
    return 'n' + str(noise_strength) + '_d' + str(depth) + '_s' + str(node_size) + '.result'


def get_noise_result_of_brain(sample, sample_ns, brain, version=None):
    name = network_analyse_result_name(sample_ns, brain.node_size, brain.depth)

    if version is not None:
        return result_vcs.load(name, version)

    vdin, adin, label = sample

    vr, ar, cr = brain.analyse((vdin, adin))

    analyse_result = (vr, ar, cr)

    result_vcs.save(analyse_result, name)

    return analyse_result


def save_sources_for_noises_and_brains(noises_samples, brains, version=None):
    noise_strength = 0
    for sample in noises_samples:
        for brain in brains:
            get_noise_result_of_brain(sample, noise_strength, brains[brain], version)
        noise_strength += 1
    return None


def yield_results_for_noises_and_brains(sample_version, noise_version=None, brains_version=None, version=None):

    for noise_strength, sample in yield_samples_with_series_noise_strength(version=noise_version,
                                                                           sample_version=sample_version):
        for node_size, brain in yield_series_trained_brain(version=brains_version):
            name = network_analyse_result_name(noise_strength, node_size)
            result = get_noise_result_of_brain(sample, noise_strength, brain, version)
            yield name, result


def yield_condition_and_results_for_noises_and_brains(sample_version, noise_version=None, brains_version=None, version=None):

    for noise_strength, sample in yield_samples_with_series_noise_strength(version=noise_version,
                                                                           sample_version=sample_version):
        for node_size, brain in yield_series_trained_brain(version=brains_version):
            result = get_noise_result_of_brain(sample, noise_strength, brain, version)
            yield noise_strength, node_size, result

def yield_results_of_noises_brain(version=None):

    if version is not None:
        for noise_strength in range(11):
            for node_size in [200, 300, 400, 500, 600, 700, 800]:
                result = result_vcs.load(
                    name=network_analyse_result_name(noise_strength, node_size),
                    version=version
                )
                yield noise_strength, node_size, result
        return

    for noise_strength in range(11):
        for node_size in [200, 300, 400, 500, 600, 700, 800]:
            get_noise_result_of_brain(
                sample=prepare_sample_with_noise(noise_strength=noise_strength, version='20220918'),
                sample_ns=noise_strength,
                brain=get_trained_brain(version='20220918', depth=1, node_size=node_size)
            )

    version = result_vcs.generate_version()
    return yield_results_of_noises_brain(version)
